﻿namespace DotRas
{
    using System;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;

    internal static class NativeMethods
    {
        public const int DNLEN = 15;
        public const int ERROR_ACCESS_DENIED = 5;
        public const int ERROR_ALREADY_EXISTS = 0xb7;
        public const int ERROR_BUFFER_TOO_SMALL = 0x25b;
        public const int ERROR_CANNOT_FIND_PHONEBOOK_ENTRY = 0x26f;
        public const int ERROR_CANNOT_OPEN_PHONEBOOK = 0x26d;
        public const int ERROR_FILE_NOT_FOUND = 2;
        public const int ERROR_INTERACTIVE_MODE = 0x2bf;
        public const int ERROR_INVALID_FUNCTION_FOR_ENTRY = 780;
        public const int ERROR_INVALID_HANDLE = 6;
        public const int ERROR_INVALID_PARAMETER = 0x57;
        public const int ERROR_NOT_NAP_CAPABLE = 0x344;
        public const int ERROR_PROTOCOL_NOT_CONFIGURED = 0x2db;
        public static readonly RasHandle INVALID_HANDLE_VALUE = new RasHandle(new IntPtr(-1));
        public const int MAX_PATH = 260;
        public const int NETBIOS_NAME_LEN = 0x10;
        public const int PWLEN = 0x100;
        public const int RAS_MaxAreaCode = 10;
        public const int RAS_MaxCallbackNumber = 0x80;
        public const int RAS_MaxDeviceName = 0x80;
        public const int RAS_MaxDeviceType = 0x10;
        public const int RAS_MaxDnsSuffix = 0x100;
        public const int RAS_MaxEntryName = 0x100;
        public const int RAS_MaxFacilities = 200;
        public const int RAS_MaxIpAddress = 15;
        public const int RAS_MaxIpxAddress = 0x15;
        public const int RAS_MaxPadType = 0x20;
        public const int RAS_MaxPhoneNumber = 0x80;
        public const int RAS_MaxReplyMessage = 0x400;
        public const int RAS_MaxUserData = 200;
        public const int RAS_MaxX25Address = 200;
        private const int RASBASE = 600;
        public const int SUCCESS = 0;
        public const int UNLEN = 0x100;

        [StructLayout(LayoutKind.Sequential)]
        public struct RAS_STATS
        {
            public int size;
            public int bytesTransmitted;
            public int bytesReceived;
            public int framesTransmitted;
            public int framesReceived;
            public int crcError;
            public int timeoutError;
            public int alignmentError;
            public int hardwareOverrunError;
            public int framingError;
            public int bufferOverrunError;
            public int compressionRatioIn;
            public int compressionRatioOut;
            public int linkSpeed;
            public int connectionDuration;
        }

        public enum RASADP
        {
            DisableConnectionQuery,
            LogOnSessionDisable,
            SavedAddressesLimit,
            FailedConnectionTimeout,
            ConnectionQueryTimeout
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASAMB
        {
            public int size;
            public int errorCode;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x11)]
            public string netBiosError;
            public byte lana;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASAUTODIALENTRY
        {
            public int size;
            public int options;
            public int dialingLocation;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string entryName;
        }

        [Flags]
        public enum RASCM
        {
            Domain = 4,
            None = 0,
            Password = 2,
            UserName = 1
        }

        [Flags]
        public enum RASCN
        {
            BandwidthAdded = 4,
            BandwidthRemoved = 8,
            Connection = 1,
            Disconnection = 2
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASCONN
        {
            public int size;
            public IntPtr handle;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string entryName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x11)]
            public string deviceType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string deviceName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
            public string phoneBook;
            public int subEntryId;
            public Guid entryId;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASCONNSTATUS
        {
            public int size;
            public RasConnectionState connectionState;
            public int errorCode;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x11)]
            public string deviceType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string deviceName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string phoneNumber;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASCREDENTIALS
        {
            public int size;
            public DotRas.NativeMethods.RASCM options;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string userName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string password;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x10)]
            public string domain;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
        public struct RASCTRYINFO
        {
            public int size;
            public int countryId;
            public int nextCountryId;
            public int countryCode;
            public int countryNameOffset;
        }

        [Flags]
        public enum RASDDFLAG : uint
        {
            LinkFailure = 0x80000000,
            NoPrompt = 2,
            PositionDlg = 1
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
        public struct RASDEVINFO
        {
            public int size;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x11)]
            public string type;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string name;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RASDIALDLG
        {
            public int size;
            public IntPtr hwndOwner;
            public DotRas.NativeMethods.RASDDFLAG flags;
            public int left;
            public int top;
            public int subEntryId;
            public int error;
            public IntPtr reserved;
            public IntPtr reserved2;
        }

        [StructLayout(LayoutKind.Sequential, Pack=4)]
        public struct RASDIALEXTENSIONS
        {
            public int size;
            public RasDialExtensionsOptions options;
            public IntPtr handle;
            public IntPtr reserved;
            public IntPtr reserved1;
            public DotRas.NativeMethods.RASEAPINFO eapInfo;
        }

        public delegate bool RasDialFunc2(int callbackId, int subEntryId, IntPtr handle, int message, RasConnectionState state, int errorCode, int extendedErrorCode);

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASDIALPARAMS
        {
            public int size;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string entryName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string phoneNumber;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string callbackNumber;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string userName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string password;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x10)]
            public string domain;
            public int subEntryId;
            public IntPtr callbackId;
        }

        [StructLayout(LayoutKind.Sequential, Pack=4)]
        public struct RASEAPINFO
        {
            public int sizeOfEapData;
            public IntPtr eapData;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASEAPUSERIDENTITY
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string userName;
            public int sizeOfEapData;
            public IntPtr eapData;
        }

        [Flags]
        public enum RASEDFLAG
        {
            CloneEntry = 4,
            InternetEntry = 0x100,
            NAT = 0x200,
            NewBroadbandEntry = 0x80,
            NewDirectEntry = 0x40,
            NewEntry = 2,
            NewPhoneEntry = 0x10,
            NewTunnelEntry = 0x20,
            NoRename = 8,
            PositionDlg = 1,
            ShellOwned = 0x40000000
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASENTRY
        {
            public int size;
            public RasEntryOptions options;
            public int countryId;
            public int countryCode;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=11)]
            public string areaCode;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string phoneNumber;
            public int alternateOffset;
            public DotRas.NativeMethods.RASIPADDR ipAddress;
            public DotRas.NativeMethods.RASIPADDR dnsAddress;
            public DotRas.NativeMethods.RASIPADDR dnsAddressAlt;
            public DotRas.NativeMethods.RASIPADDR winsAddress;
            public DotRas.NativeMethods.RASIPADDR winsAddressAlt;
            public int frameSize;
            public RasNetworkProtocols networkProtocols;
            public RasFramingProtocol framingProtocol;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
            public string script;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
            public string autoDialDll;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
            public string autoDialFunc;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x11)]
            public string deviceType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string deviceName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x21)]
            public string x25PadType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0xc9)]
            public string x25Address;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0xc9)]
            public string x25Facilities;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0xc9)]
            public string x25UserData;
            public int channels;
            public int reserved1;
            public int reserved2;
            public int subentries;
            public RasDialMode dialMode;
            public int dialExtraPercent;
            public int dialExtraSampleSeconds;
            public int hangUpExtraPercent;
            public int hangUpExtraSampleSeconds;
            public int idleDisconnectSeconds;
            public RasEntryType entryType;
            public RasEncryptionType encryptionType;
            public int customAuthKey;
            public Guid id;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
            public string customDialDll;
            public RasVpnStrategy vpnStrategy;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASENTRYDLG
        {
            public int size;
            public IntPtr hwndOwner;
            public DotRas.NativeMethods.RASEDFLAG flags;
            public int left;
            public int top;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string entryName;
            public int error;
            public IntPtr reserved;
            public IntPtr reserved2;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASENTRYNAME
        {
            public int size;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x101)]
            public string name;
            public RasPhoneBookType phoneBookType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x105)]
            public string phoneBookPath;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RASIPADDR
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
            public byte[] addr;
        }

        public enum RasNotifierType
        {
            [Obsolete("Use the RasDialFunc2 value.", true)]
            RasDialFunc = 0,
            [Obsolete("Use the RasDialFunc2 value.", true)]
            RasDialFunc1 = 1,
            RasDialFunc2 = 2
        }

        public enum RASPBDEVENT
        {
            AddEntry = 1,
            DialEntry = 4,
            EditEntry = 2,
            EditGlobals = 5,
            NoUser = 6,
            NoUserEdit = 7,
            RemoveEntry = 3
        }

        [Flags]
        public enum RASPBDFLAG : uint
        {
            ForceCloseOnDial = 2,
            NoUser = 0x10,
            PositionDlg = 1,
            UpdateDefaults = 0x80000000
        }

        [StructLayout(LayoutKind.Sequential, Pack=4)]
        public struct RASPBDLG
        {
            public int size;
            public IntPtr hwndOwner;
            public DotRas.NativeMethods.RASPBDFLAG flags;
            public int left;
            public int top;
            public IntPtr callbackId;
            public DotRas.NativeMethods.RasPBDlgFunc callback;
            public int error;
            public IntPtr reserved;
            public IntPtr reserved2;
        }

        public delegate void RasPBDlgFunc(int callbackId, DotRas.NativeMethods.RASPBDEVENT eventType, string message, IntPtr data);

        [StructLayout(LayoutKind.Sequential)]
        public struct RASPPPCCP
        {
            public int size;
            public int errorCode;
            public RasCompressionType compressionAlgorithm;
            public RasCompressionOptions options;
            public RasCompressionType serverCompressionAlgorithm;
            public RasCompressionOptions serverOptions;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASPPPIP
        {
            public int size;
            public int errorCode;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x10)]
            public string ipAddress;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x10)]
            public string serverIPAddress;
            public RasIPOptions options;
            public RasIPOptions serverOptions;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASPPPIPX
        {
            public int size;
            public int errorCode;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x16)]
            public string ipxAddress;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
        public struct RASPPPLCP
        {
            public int size;
            [MarshalAs(UnmanagedType.Bool)]
            public bool bundled;
            public int errorCode;
            public RasLcpAuthenticationType authenticationProtocol;
            public RasLcpAuthenticationDataType authenticationData;
            public int eapTypeId;
            public RasLcpAuthenticationType serverAuthenticationProtocol;
            public RasLcpAuthenticationDataType serverAuthenticationData;
            public int serverEapTypeId;
            [MarshalAs(UnmanagedType.Bool)]
            public bool multilink;
            public int terminateReason;
            public int serverTerminateReason;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x400)]
            public string replyMessage;
            public RasLcpOptions options;
            public RasLcpOptions serverOptions;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASPPPNBF
        {
            public int size;
            public int errorCode;
            public int netBiosErrorCode;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x11)]
            public string netBiosErrorMessage;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x11)]
            public string workstationName;
            public byte lana;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
        public struct RASSLIP
        {
            public int size;
            public int errorCode;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x10)]
            public string ipAddress;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=4)]
        public struct RASSUBENTRY
        {
            public int size;
            public int flags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x11)]
            public string deviceType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string deviceName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x81)]
            public string phoneNumber;
            public int alternateOffset;
        }
    }
}

